package job.work.utils;

import com.google.common.collect.Maps;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * @Classname DateUtil
 * @author zzy
 * @Date 2020/8/15 11:43
 * @Created by Administrator
 */

@Slf4j
public class DateUtil {

    private static String LONGDATE_DATEMONTH = "yyyy-MM";

    private static String LONGDATE_DATE = "yyyy-MM-dd";

    /**
     * Map的Key，用于获取某月第一天{@link #LONGDATE_DATE}格式的日期
     */
    public static final String START_DATE = "START_DATE";

    /**
     * Map的Key，用于获取某月最后一天{@link #LONGDATE_DATE}格式的日期
     */
    public static final String STOP_DATE = "STOP_DATE";

    /**
     * 获得指定年月日期的月份第一天和最后一天
     * 如果日期在本月以内 则返回当天日期和月末日期
     * @param yearMonth 2019-05
     * @return
     */
    public static Map<String, String> getStartDateAndStopDate(String yearMonth) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(LONGDATE_DATEMONTH);
        Calendar cale = getCalendar(sdf.parse(yearMonth));
        SimpleDateFormat format = new SimpleDateFormat(LONGDATE_DATE);
        String firstDay, lastDay;
        if (isThisTime(cale.getTime().getTime(),LONGDATE_DATEMONTH)) {
            firstDay = format.format(new Date());
        } else {
            cale.add(Calendar.MONTH, 0);
            cale.set(Calendar.DAY_OF_MONTH, 1);
            firstDay = format.format(cale.getTime());
        }
        cale.add(Calendar.MONTH, 1);
        cale.set(Calendar.DAY_OF_MONTH, 0);
        lastDay = format.format(cale.getTime());
        Map<String, String> date = new HashMap<String, String>();
        date.put(START_DATE, firstDay);
        date.put(STOP_DATE, lastDay);
        return date;
    }

    public static Calendar getCalendar(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        return calendar;
    }

    /**
     * 时间是否在本月内
     * @param time 时间戳
     * @param pattern 匹配格式
     * @return
     */
    public static boolean isThisTime(long time, String pattern) {
        Date date = new Date(time);
        SimpleDateFormat sdf = new SimpleDateFormat(pattern);
        String param = sdf.format(date);
        String now = sdf.format(new Date());
        if (param.equals(now)) {
            return true;
        }
        return false;
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class DateTimeStamp {
        private Long startTimeStamp;
        private Long endTimeStamp;
    }

    /**
     * 获取时间段每天开始和结束的时间戳
     * @param beginTime
     * @param endTime
     * @return
     * @throws ParseException
     */
    public static Map<String,DateTimeStamp> getAllTimeStamp(String beginTime, String endTime) throws ParseException{
        Map<String,DateTimeStamp> allTimeStamp = Maps.newHashMap();
        SimpleDateFormat sdf = new SimpleDateFormat(LONGDATE_DATE);
        Calendar cal = getCalendar(sdf.parse(beginTime));
        // 判断是否是同一天
        if(isDay(beginTime,endTime)) {
            setTimeStampList(allTimeStamp,cal);
            return allTimeStamp;
        }
        setTimeStampList(allTimeStamp,cal);
        while (true) {
            cal.add(Calendar.DAY_OF_MONTH, 1);
            if (sdf.parse(endTime).after(cal.getTime())) {
                setTimeStampList(allTimeStamp,cal);
            } else {
                break;
            }
        }
        setTimeStampList(allTimeStamp,cal);
        return allTimeStamp;
    }

    /**
     * 判断两个人日期是否为同一天
     * @param beginDate
     * @param endDate
     * @return
     * @throws ParseException
     */
    public static boolean isDay(String beginDate, String endDate) throws ParseException{
        SimpleDateFormat sdf = new SimpleDateFormat(LONGDATE_DATE);
        return org.apache.commons.lang.time.DateUtils.isSameDay(sdf.parse(beginDate),sdf.parse(endDate));
    }

    private static void setTimeStampList(Map<String,DateTimeStamp> allTimeStamp, Calendar cal) {
        DateTimeStamp dateTimeStamp = new DateTimeStamp();
        long beginSt = getFirstTime(cal).getTime() / 1000;
        dateTimeStamp.setStartTimeStamp(beginSt);
        long endSt = getLastTime(cal).getTime() / 1000;
        dateTimeStamp.setEndTimeStamp(endSt);
        String result = new SimpleDateFormat("yyyy-MM-dd").format(new Date(beginSt * 1000));
        allTimeStamp.put(result,dateTimeStamp);
    }

    /**
     * 获取当天起始时间
     * @param todayStart
     * @return
     */
    public static Date getFirstTime(Calendar todayStart) {
        todayStart.set(Calendar.HOUR_OF_DAY, 0);
        todayStart.set(Calendar.MINUTE, 0);
        todayStart.set(Calendar.SECOND, 0);
        todayStart.set(Calendar.MILLISECOND, 0);
        return todayStart.getTime();
    }

    /**
     * 获取当天结束时间
     * @param todayEnd
     * @return
     */
    public static Date getLastTime(Calendar todayEnd) {
        todayEnd.set(Calendar.HOUR_OF_DAY, 23);
        todayEnd.set(Calendar.MINUTE, 59);
        todayEnd.set(Calendar.SECOND, 59);
        todayEnd.set(Calendar.MILLISECOND, 999);
        return todayEnd.getTime();
    }





    /**
     * 判断当前日期是否在[startDate, endDate]区间
     *
     * @param startDate 开始日期
     * @param endDate 结束日期
     * @author jqlin
     * @return
     */
    public static boolean isEffectiveDate(Date startDate, Date endDate){
        if(startDate == null || endDate == null){
            return false;
        }
        long currentTime = System.currentTimeMillis();
        if(currentTime >= startDate.getTime()
                && currentTime <= endDate.getTime()){
            return true;
        }
        return false;
    }

    /**
     * date类型进行格式化输出（返回类型：String）
     * @param date
     * @return
     */
    public static String dateFormat(Date date) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH");
        String dateString = formatter.format(date);
        return dateString;
    }

    /**
     * date类型进行格式化输出（返回类型：String）
     * @param date
     * @return
     */
    public static String dateFormats(Date date) {
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
        String dateString = formatter.format(date);
        return dateString;
    }


    /**
     * 获取两个日期之间间隔天数
     * @param startDate
     * @param endDate
     * @return
     */

    public static Long getTwoDay(Date startDate, Date endDate) {

        long day = 0;
        try {
            day = (endDate.getTime() - startDate.getTime()) / (24 * 60 * 60 * 1000);

        } catch (Exception e) {

            return 0L;
        }
        return day;
    }

    public static final String yyyyMMddHHmmss = "yyyyMMddHHmmss";

    public static Date dateFormat(String date, String format) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        try {
            return formatter.parse(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
    * 获取当天的开始时间和结束时间
    * */
    public static Map<String,Date> makeTime(){
        Calendar ca = Calendar.getInstance();
        ca.setTime(new Date());
        ca.add(Calendar.DATE, 0);
        Date firstTime = DateUtil.getFirstTime(ca);
        Date lastTime = DateUtil.getLastTime(ca);
        Map<String,Date> map = new HashMap<>();
        map.put("firstTime",firstTime);
        map.put("lastTime",lastTime);
        return map;
    }




    public static void main(String[] args) throws ParseException {

        Date date = new Date();

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date parse = sdf.parse("2020-10-31 13:10:05");
        Long twoDay = getTwoDay(parse, date);
        log.info("输出时间比较--->{}",twoDay>=1L);
        System.out.println("------------------------------");

        Calendar ca = Calendar.getInstance();
        ca.setTime(new Date());
        ca.add(Calendar.DATE, 1);
        Date firstTime = getFirstTime(ca);
        Date lastTime = getLastTime(ca);
        String s = firstTime.toString();
        System.out.println(s);
        System.out.println(lastTime);

    }

}